package org.jeecg.modules.awpay.controller;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.alipay.bo.PaymentBO;
import org.jeecg.modules.awpay.common.request.*;
import org.jeecg.modules.awpay.common.result.*;
import org.jeecg.modules.awpay.service.AliPayService;
import org.jeecg.modules.awpay.service.WeiXinPayService;
import com.github.binarywang.wxpay.bean.result.*;
import org.jeecg.modules.awpay.util.PayCommonUtil;
import org.jeecg.modules.awpay.util.XMLUtil;
import org.jeecg.modules.gwcjava.jiekou.entity.*;
import org.jeecg.modules.gwcjava.jiekou.service.BusinessLogicService;
import org.jeecg.modules.gwcjava.jiekou.service.MlccUserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.*;


/**
 *  微信支付，控制器
 *
 * @author wangziyang
 * */
@Api(tags="后台支付控制器")
@RestController
@RequestMapping("/WxPay")
@Slf4j
public class WxPayController {
    /**查询用户信息*/
    @Autowired
    private MlccUserInfoService userservice;
    @Autowired
    private BusinessLogicService logicService;
    //微信支付
    @Resource
    private WeiXinPayService weiXinPayService;

    @PostMapping(value = "/wx/pay/order_create")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public Result<WxPayUnifiedOrderResult> create(OrderCreateRequest request)  {
        MlccUserInfo userInfo = userservice.queryUserinfoByusername(request.getToken(),3);
        if(userInfo==null){
            return Result.error(-1,"token失效，请重新登录");
        }
        if(request.getOrderSn()==null || "".equals(request.getOrderSn())){
            return Result.error(-1,"订单编号不能为空");
        }
        if("0".equals(request.getOrderType())){
            request.setOrderName("面料下单");
            request.setSubject("面料下单");
            request.setBody("铭朗云服装定制面料下单");
            PaymentBO paymentBO = logicService.query_paymentBODetail(request.getOrderSn(),request.getOrderType());
            if(paymentBO!=null){
                request.setPayChannel("WXPAY_NATIVE");
                request.setOrderMoney(paymentBO.getOrderMoney());
                request.setPayAmount(paymentBO.getOrderMoney());
                request.setOrderSn(request.getOrderSn());
                return weiXinPayService.create(request);
            }else {
                return Result.error(-1,"下单失败");
            }
        }else if("1".equals(request.getOrderType())){
            request.setOrderName("个订下单");
            request.setSubject("个订下单");
            request.setBody("铭朗云服装定制个订下单");
            PaymentBO paymentBO = logicService.query_paymentBODetail(request.getOrderSn(),request.getOrderType());
            if(paymentBO!=null){
                request.setPayChannel("WXPAY_NATIVE");
                request.setOrderMoney(paymentBO.getOrderMoney());
                request.setPayAmount(paymentBO.getOrderMoney());
                request.setOrderSn(request.getOrderSn());
                return weiXinPayService.create(request);
            }else {
                return Result.error(-1,"下单失败");
            }
        }else if("2".equals(request.getOrderType())){
            request.setOrderName("团订下单");
            request.setSubject("团订下单");
            request.setBody("铭朗云服装定制团订下单");
            PaymentBO paymentBO = logicService.query_paymentBODetail(request.getOrderSn(),request.getOrderType());
            if(paymentBO!=null){
                request.setPayChannel("WXPAY_NATIVE");
                request.setOrderMoney(paymentBO.getOrderMoney());
                request.setPayAmount(paymentBO.getOrderMoney());
                request.setOrderSn(request.getOrderSn());
                return weiXinPayService.create(request);
            }else {
                return Result.error(-1,"下单失败");
            }
        }else if("3".equals(request.getOrderType())){
            //8位随机数
            int random=new Random().nextInt(100000)+1;//为变量赋随机值1-99999999;
            //先创建充值订单
            Long startTs = System.currentTimeMillis(); // 当前时间戳
            String charge_sn = "WXCHRAG"+startTs+random;
            ChargeOrderInfo chargeOrderInfo = new ChargeOrderInfo();
            chargeOrderInfo.setChargeSn(charge_sn);
            chargeOrderInfo.setApplyMethod(request.getApplyMethod());
            chargeOrderInfo.setUserId(userInfo.getId().toString());
            chargeOrderInfo.setMoney(request.getOrderSn());
            chargeOrderInfo.setStatus(0);//假设充值成功
            userservice.create_chargeOrder(chargeOrderInfo);
            request.setOrderName("用户余额充值");
            request.setSubject("用户余额充值");
            request.setBody("铭朗云用户余额充值订单");
            request.setPayChannel("WXPAY_NATIVE");
            request.setOrderMoney(request.getOrderSn());
            request.setPayAmount(request.getOrderSn());
            request.setOrderSn(charge_sn);
            return weiXinPayService.create(request);
        }
        else {
            return Result.error(-1,"请传入订单类型");
        }
//        }catch (Exception e){
//            return Result.error(-1,"失败="+e);
//        }
    }


    @ResponseBody
    @RequestMapping(value = "/wx/pay/order/query",method = RequestMethod.POST)
    public Result<WxPayOrderQueryResult> query(@RequestBody OrderQueryRequest request)  {
        if(StringUtils.isEmpty(request.getOutTradeNo())){
            return Result.error(-1,"outTradeNo不能为空");
        }
        return weiXinPayService.query(request);
    }

    @ResponseBody
    @RequestMapping(value = "/wx/pay/order/close",method = RequestMethod.POST)
    public Result<WxPayOrderCloseResult> close(@RequestBody OrderCloseRequest request)  {
        if(StringUtils.isEmpty(request.getOutTradeNo())){
            return Result.error(-1,"outTradeNo不能为空");
        }
        return weiXinPayService.close(request);
    }

    @ResponseBody
    @RequestMapping(value = "/wx/pay/order/refund",method = RequestMethod.POST)
    public Result<WxPayRefundResult> query(@RequestBody OrderRefundRequest request)  {
        if(StringUtils.isEmpty(request.getOutTradeNo())){
            return Result.error(-1,"outTradeNo不能为空");
        }
        if(StringUtils.isEmpty(request.getPayAmount())){
            return Result.error(-1,"payAmount不能为空");
        }
        if(StringUtils.isEmpty(request.getRefundAmount())){
            return Result.error(-1,"refundAmount不能为空");
        }
        if(StringUtils.isEmpty(request.getRefundReason())){
            return Result.error(-1,"refundReason不能为空");
        }
        String outRefundNo = "R" + IdWorker.getId();
        request.setOutRefundNo(outRefundNo);
        return weiXinPayService.refund(request);
    }

    @ResponseBody
    @RequestMapping(value = "/wx/pay/refund/query",method = RequestMethod.POST)
    public Result<WxPayRefundQueryResult> query(@RequestBody RefundQueryRequest request)  {
        if(StringUtils.isEmpty(request.getOutTradeNo())){
            return Result.error(-1,"outTradeNo不能为空");
        }
        return weiXinPayService.refundQuery(request);
    }

    /**
     * 微信支付回调
     * */
    @PostMapping(value = "wx/fallback")
    @Transactional(rollbackFor = Exception.class)
    public String weixin_notify(HttpServletRequest request, HttpServletResponse response) throws Exception{
        //读取参数
        InputStream inputStream ;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s ;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null){
            sb.append(s);
        }
        in.close();
        inputStream.close();
        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());
        //过滤空 设置 TreeMap
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);
            String v = "";
            if(null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        // 账号信息
        String key = CommonConstant.WX_APP_SECRET; // key
        //判断签名是否正确
        if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {
            //处理业务开始
            //------------------------------
            String resXml = "";
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
                //执行自己的业务逻辑
                String wx_out_trade_no = (String)packageParams.get("out_trade_no");//随机产生的商品id
//                System.out.println("out_trade_no:"+wx_out_trade_no);
                //根据微信订单编号查询
                WxOrderStatus wxOrderStatus = logicService.query_WxOrderStatusDetailBysn(wx_out_trade_no);
                if(wxOrderStatus!=null){
                    if(wxOrderStatus.getStatus()==0){//说明发起支付了-回到正确逻辑
                        if(wxOrderStatus.getOrderType()==0){//面料订单
                            FabricOrderInfo fabricOrderInfo = logicService.query_fabricOrderDetailBycode(wxOrderStatus.getOrderSn());
                            if(fabricOrderInfo!=null) {
                                if (fabricOrderInfo.getStatus() == 0) {
                                    Long startTs = System.currentTimeMillis(); // 当前时间戳
                                    //8位随机数
                                    int random = new Random().nextInt(100000) + 1;//为变量赋随机值1-99999999;
                                    String category_code = startTs.toString() + random;//流水id
                                    String genzong_id = "WXGZB" + startTs.toString() + random;//跟踪id
                                    String event_id = "WXEVENT" + startTs.toString() + random;//事件id
                                    //执行修改面料订单的业务
                                    logicService.change_order_status(wxOrderStatus.getOrderSn(), 0,1);
                                    //第二部-插入流水表
                                    BusinessWaterInfo datainfo = new BusinessWaterInfo();
                                    datainfo.setId(category_code);
                                    datainfo.setYewuDeatil("面料订单");
                                    datainfo.setOrderId(fabricOrderInfo.getId().toString());
                                    datainfo.setCostMoney(fabricOrderInfo.getOrderMoney());
                                    datainfo.setOrderSn(wxOrderStatus.getOrderSn());
                                    datainfo.setRemark("面料订单");
                                    datainfo.setYewuInstructions("面料下单");
                                    datainfo.setUserId(fabricOrderInfo.getUserId());
                                    datainfo.setStoreId(fabricOrderInfo.getStoreId());
                                    datainfo.setApplyMethod(2);
                                    datainfo.setStatus(2);
                                    datainfo.setType(0);
                                    datainfo.setSysOrgCode(fabricOrderInfo.getSysOrgCode());
                                    logicService.insert_into_water(datainfo);
                                    //第三部-插入订单跟踪表
                                    logicService.insert_into_ordertracking(genzong_id, wxOrderStatus.getOrderSn(), "0", "面料订单在线支付", "微信在线扫码支付", 1);
                                    //第四部-插入订单事件表
                                    logicService.insert_into_orderevent(event_id, "你有一条新的面料订单", 0, wxOrderStatus.getOrderSn(), "0", "你有一条新的面料订单");
                                }
                                //修改微信订单的状态
                                logicService.update_wxorder_status(wxOrderStatus.getId().toString(),"2");
                            }
                        }else if(wxOrderStatus.getOrderType()==1){//个订
                            //根据订单编号查询订单信息
                            SingleOrderInfo singleOrderInfo = logicService.query_signorder(wxOrderStatus.getOrderSn());
                            if(singleOrderInfo!=null) {
                                if (singleOrderInfo.getStatus() == 11) {
                                    Long startTs = System.currentTimeMillis(); // 当前时间戳
                                    //8位随机数
                                    int random = new Random().nextInt(1000000) + 1;//为变量赋随机值1-99999999;
                                    String category_code = startTs.toString() + random;//流水id
                                    String genzong_id = "WXGZB" + startTs.toString() + random;//跟踪id
                                    String event_id = "WXEVENT" + startTs.toString() + random;//事件id
                                    //执行修改个订单的业务
                                    logicService.change_order_status(wxOrderStatus.getOrderSn(), 1,1);
                                    //第二部-插入流水表
                                    BusinessWaterInfo datainfo = new BusinessWaterInfo();
                                    datainfo.setId(category_code);
                                    datainfo.setYewuDeatil("个订下单");
                                    datainfo.setOrderId(singleOrderInfo.getId().toString());
                                    datainfo.setCostMoney(singleOrderInfo.getOrderMoney());
                                    datainfo.setOrderSn(wxOrderStatus.getOrderSn());
                                    datainfo.setRemark("个订订单");
                                    datainfo.setYewuInstructions("个订下单");
                                    datainfo.setUserId(singleOrderInfo.getUserId());
                                    datainfo.setStoreId(singleOrderInfo.getStoreId());
                                    datainfo.setApplyMethod(2);
                                    datainfo.setStatus(2);
                                    datainfo.setType(1);
                                    datainfo.setSysOrgCode(singleOrderInfo.getSysOrgCode());
                                    logicService.insert_into_water(datainfo);
                                    //第三部-插入订单跟踪表
                                    logicService.insert_into_ordertracking(genzong_id, wxOrderStatus.getOrderSn(), "1", "个订订单在线支付", "微信在线扫码支付", 1);
                                    //第四部-插入订单事件表
                                    logicService.insert_into_orderevent(event_id, "你有一条新的个订订单", 0, wxOrderStatus.getOrderSn(), "1", "你有一条新的个订订单");
                                }
                                //修改微信订单的状态
                                logicService.update_wxorder_status(wxOrderStatus.getId().toString(),"2");
                            }
                        }else if(wxOrderStatus.getOrderType()==2){//团订
                            TeamOrderInfo fabricOrderInfo = logicService.queryOrderDetail(wxOrderStatus.getOrderSn());
                            if(fabricOrderInfo!=null) {
                                if (fabricOrderInfo.getStatus() == 11) {
                                    Long startTs = System.currentTimeMillis(); // 当前时间戳
                                    //8位随机数
                                    int random = new Random().nextInt(10000) + 1;//为变量赋随机值1-99999999;
                                    String category_code = startTs.toString() + random;//流水id
                                    String genzong_id = "WXGZB" + startTs.toString() + random;//跟踪id
                                    String event_id = "WXEVENT" + startTs.toString() + random;//事件id
                                    //执行修改团订订单的业务
                                    logicService.change_order_status(wxOrderStatus.getOrderSn(), 2,1);
                                    //第二部-插入流水表
                                    BusinessWaterInfo datainfo = new BusinessWaterInfo();
                                    datainfo.setId(category_code);
                                    datainfo.setYewuDeatil("团订订单");
                                    datainfo.setOrderId(fabricOrderInfo.getId().toString());
                                    datainfo.setCostMoney(fabricOrderInfo.getOrderMoney());
                                    datainfo.setOrderSn(wxOrderStatus.getOrderSn());
                                    datainfo.setRemark("团订订单");
                                    datainfo.setYewuInstructions("团订下单");
                                    datainfo.setUserId(fabricOrderInfo.getUserId());
                                    datainfo.setStoreId(fabricOrderInfo.getStoreId());
                                    datainfo.setApplyMethod(2);
                                    datainfo.setStatus(2);
                                    datainfo.setType(2);
                                    datainfo.setSysOrgCode(fabricOrderInfo.getSysOrgCode());
                                    logicService.insert_into_water(datainfo);
                                    //第三部-插入订单跟踪表
                                    logicService.insert_into_ordertracking(genzong_id, wxOrderStatus.getOrderSn(), "2", "团订订单在线支付", "微信在线扫码支付", 1);
                                    //第四部-插入订单事件表
                                    logicService.insert_into_orderevent(event_id, "你有一条新的团订订单", 0, wxOrderStatus.getOrderSn(), "2", "你有一条新的团订订单");
                                }
                                //修改微信订单的状态
                                logicService.update_wxorder_status(wxOrderStatus.getId().toString(),"2");
                            }
                        }else {
                            //根据充值订单流水号查询（已充值就修改用户余额）
                            ChargeOrderInfo datainfoDetail = userservice.queryChargeOrderInfo(wxOrderStatus.getOrderSn());
                            String oldbalance = "0.00";
                            Long systemtime = System.currentTimeMillis();
                            DecimalFormat df = new DecimalFormat("0.00");
                            //修改用户余额
                            if(datainfoDetail!=null){
                                MlccUserInfo userInfo = userservice.queryUserinfoByusername(datainfoDetail.getUserId(),0);
                                if(userInfo!=null){
                                    oldbalance = userInfo.getAccountBalance();
                                    //赋值新的余额
                                    double newbalance = Double.parseDouble(oldbalance)+Double.parseDouble(datainfoDetail.getMoney());
                                    userservice.update_user_balance(df.format(newbalance),userInfo.getId().toString());
                                    //插入财务流水表
                                    userservice.insert_financial(userInfo.getId().toString(),"FINA"+systemtime,"前端用户微信充值",datainfoDetail.getMoney(),
                                            df.format(newbalance));
                                    //修改充值状态
                                    userservice.update_chargeOrder_status(datainfoDetail.getId().toString(),"1");
                                }
                            }
                            //修改微信订单的状态
                            logicService.update_wxorder_status(wxOrderStatus.getId().toString(),"2");
                        }
                    }
                }
                System.out.println("微信支付成功");
                //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                System.out.println("支付失败,错误信息：" + packageParams.get("err_code"));
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }
            //------------------------------
            //处理业务完毕
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
            return resXml;
        } else{
            System.out.println("通知签名验证失败");
            return "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
    }


}
